home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 255_01 / gpline.asm < prev    next >
Assembly Source File  |  1988-03-28  |  10KB  |  434 lines

  1.       page     80,132
  2.       page
  3. ;
  4. ;      Kent Cedola
  5. ;      2015 Meadow Lake Court
  6. ;      Norfolk, Virginia  23518
  7. ;
  8.  
  9. dgroup      group  _data
  10.  
  11. _data     segment word public 'data'
  12.       assume ds:dgroup
  13.  
  14.       extrn  _gdcolor:byte,_gdmerge:byte
  15.       extrn  _gdcur_x:word,_gdcur_y:word
  16.       extrn  _gdvw_x1:word,_gdvw_x2:word,_gdvw_x3:word
  17.       extrn  _gdvw_y1:word,_gdvw_y2:word,_gdvw_y3:word
  18.       extrn  _gdc_flg:byte,_gds_flg:byte
  19.       extrn  _gdstyle:dword,_gdgseg:word
  20.  
  21. _data      ends
  22.  
  23. _text     segment byte public 'code'
  24.  
  25.       assume cs:_text,ds:dgroup
  26.       public _gpline
  27. _gpline   proc     near
  28.  
  29.       push     bp
  30.       mov     bp,sp
  31.       push     si
  32.       push     di
  33.  
  34.       mov     cx,_gdcur_x           ; Load starting X coordinate (X1)
  35.       mov     bx,_gdcur_y           ; Load starting Y coordinate (Y1)
  36.       mov     si,[bp+4]           ; Load ending X coordinate (X2)
  37.       mov     di,[bp+6]           ; Load ending Y coordinate (Y2)
  38.       mov     _gdcur_x,si           ; Store new current (X,Y) coordinates
  39.       mov     _gdcur_y,di           ;   ...
  40.  
  41.       mov     _gdc_flg,0           ; Set the clipping flag to zero
  42.  
  43. ;      Perform the Cohen-Sutherland two-step clipping algorithm, in which a
  44. ;  four-element code indicates the position of a point.  From pages 36-37 of
  45. ;  the book "Microcomputer Displays, Graphics, and Animation" by Bruce Atwick.
  46.  
  47. dline01:
  48.       XOR     AX,AX
  49.  
  50. ;      Generate 4-element start and end point codes
  51.  
  52.       CMP     BX,_gdvw_y1
  53.       JGE     $+5
  54.       OR     AH,8
  55.       CMP     BX,_gdvw_y2
  56.       JLE     $+5
  57.       OR     AH,4
  58.       CMP     CX,_gdvw_x1
  59.       JGE     $+5
  60.       OR     AH,2
  61.       CMP     CX,_gdvw_x2
  62.       JLE     $+5
  63.       OR     AH,1
  64.  
  65.       CMP     DI,_gdvw_y1
  66.       JGE     $+4
  67.       OR     AL,8
  68.       CMP     DI,_gdvw_y2
  69.       JLE     $+4
  70.       OR     AL,4
  71.       CMP     SI,_gdvw_x1
  72.       JGE     $+4
  73.       OR     AL,2
  74.       CMP     SI,_gdvw_x2
  75.       JLE     $+4
  76.       OR     AL,1
  77.  
  78.       OR     AX,AX
  79.       JNZ     dline15
  80.       JMP     dline09
  81. dline15:
  82.       mov     _gdc_flg,1
  83.       TEST     AH,AL
  84.       JZ     dline02
  85.       mov     _gdc_flg,2
  86.       jmp     theend
  87. dline02:
  88.       OR     AL,AL
  89.       JNZ     dline03
  90.  
  91. ;      Swap start and end points
  92.  
  93.       XCHG     CX,SI               ;
  94.       XCHG     BX,DI               ;
  95.       XCHG     AH,AL
  96.  
  97. dline03:
  98.  
  99.       TEST     AL,2
  100.       JNZ     dline06
  101.       TEST     AL,4
  102.       JNZ     dline07
  103.       TEST     AL,8
  104.       JNZ     dline08
  105. dline05:
  106.       MOV     BP,DI
  107.       SUB     BP,BX
  108.       MOV     AX,_gdvw_x2
  109.       SUB     AX,CX
  110.       IMUL     BP
  111.       MOV     BP,SI
  112.       SUB     BP,CX
  113.       IDIV     BP
  114.       ADD     AX,BX
  115.       MOV     SI,_gdvw_x2
  116.       MOV     DI,AX
  117.       JMP     dline01
  118. dline06:
  119.       MOV     BP,DI
  120.       SUB     BP,BX
  121.       MOV     AX,_gdvw_x1
  122.       SUB     AX,CX
  123.       IMUL     BP
  124.       MOV     BP,SI
  125.       SUB     BP,CX
  126.       IDIV     BP
  127.       ADD     AX,BX
  128.       MOV     SI,_gdvw_x1
  129.       MOV     DI,AX
  130.       JMP     dline01
  131. dline07:
  132.       MOV     BP,SI
  133.       SUB     BP,CX
  134.       MOV     AX,_gdvw_y2
  135.       SUB     AX,BX
  136.       IMUL     BP
  137.       MOV     BP,DI
  138.       SUB     BP,BX
  139.       IDIV     BP
  140.       ADD     AX,CX
  141.       MOV     SI,AX
  142.       MOV     DI,_gdvw_y2
  143.       JMP     dline01
  144. dline08:
  145.       MOV     BP,SI
  146.       SUB     BP,CX
  147.       MOV     AX,_gdvw_y1
  148.       SUB     AX,BX
  149.       IMUL     BP
  150.       MOV     BP,DI
  151.       SUB     BP,BX
  152.       IDIV     BP
  153.       ADD     AX,CX
  154.       MOV     SI,AX
  155.       MOV     DI,_gdvw_y1
  156.       JMP     dline01
  157. dline09:
  158.  
  159.       mov     dx,03CEh           ; Load address of EGA graphic controller
  160.       mov     ah,_gdmerge           ; Load current merge setting
  161.       mov     al,03h            ; Load address of merge register
  162.       out     dx,ax               ; Set the graphic controller function
  163.       mov     ax,00205h           ; Load parameters for write mode #2
  164.       out     dx,ax               ; Set the graphic controller write mode
  165.  
  166.       mov     dx,si
  167.  
  168.       cmp     dx,cx               ; Is X2 >= X1?
  169.       jae     noxchg            ;   Yes, continue
  170.       xchg     cx,dx               ;   No, then switch (X1,Y1) with (X2,Y2)
  171.       xchg     bx,di               ;     ...
  172. noxchg:
  173.       sub     dx,cx               ; Compute Delta X := X2 - X1;
  174.       sub     di,bx               ; Compute Delta Y := Y2 - Y1;
  175.  
  176.       mov     si,bx               ; Compute SI = Y * 80 for row offset
  177.       shl     si,1               ;   ... (SI = Y * 2)
  178.       shl     si,1               ;   ... (SI = Y * 4)
  179.       add     si,bx               ;   ... (SI = Y * 5)
  180.       shl     si,1               ;   ... (SI = Y * 10)
  181.       shl     si,1               ;   ... (SI = Y * 20)
  182.       shl     si,1               ;   ... (SI = Y * 40)
  183.       shl     si,1               ;   ... (SI = Y * 80)
  184.       mov     bx,cx               ; Compute BX = X / 8 for column offset
  185.       shr     bx,1               ;   ... (BX = X / 2)
  186.       shr     bx,1               ;   ... (BX = X / 4)
  187.       shr     bx,1               ;   ... (BX = X / 8)
  188.       add     bx,si               ; Compute BX = BX + SI, first byte
  189.  
  190.       mov     si,dx               ; SI now contains delta X
  191.  
  192.       mov     dx,03CEh           ;
  193.       mov     al,8               ;
  194.       out     dx,al               ;
  195.       inc     dx               ;
  196.  
  197.       and     cl,7               ; Compute AL = starting bit mask
  198.       mov     al,080h           ;   ... load default of bit 0
  199.       ror     al,cl               ;   ... rotate to the starting bit mask
  200.  
  201.       cmp     _gds_flg,0           ; Do we use the current line style?
  202.       jne     style
  203.       jmp     line
  204. style:
  205.       push     si
  206.       les     si,_gdstyle
  207.       cmp     byte ptr es:[si],1
  208.       jne     style00
  209.       mov     ah,es:[si+1]
  210.       pop     si
  211.       jmp     line
  212. style00:
  213.       pop     si
  214.       mov     [bp+4],si
  215.       mov     [bp+6],di
  216.       or     di,di
  217.       jns     style02
  218.       neg     di
  219.       cmp     di,si
  220.       ja     style01
  221.       jmp     octant8
  222. style01:
  223.       jmp     octant7
  224. style02:
  225.       cmp     di,si
  226.       ja     octant2
  227. octant1:
  228.       mov     cx,si               ; Count Down = DX
  229.       mov     di,si               ; Error Register = -DX/2
  230.       shr     di,1               ;   ...
  231.       neg     di               ;   ...
  232.       les     si,_gdstyle
  233.       mov     ah,es:[si]
  234.       inc     si
  235. octant1L:
  236.       call     putdot
  237.  
  238.       ror     al,1               ; Compute X := X + 1;
  239.       adc     bx,0               ;   ...
  240.       add     di,[bp+6]           ;
  241.       jle     octant1L           ;
  242.       add     bx,80               ; Compute Y := Y + 1;
  243.       sub     di,[bp+4]           ;
  244.       jmp     short octant1L        ;
  245.  
  246. octant2:
  247.       mov     cx,di               ; Count Down = DY
  248.       shr     di,1               ; Error Register = -DX/2
  249.       neg     di               ;   ...
  250.       les     si,_gdstyle
  251.       mov     ah,es:[si]
  252.       inc     si
  253. octant2L:
  254.       call     putdot
  255.  
  256.       add     bx,80               ; Compute Y := Y + 1;
  257.       add     di,[bp+4]           ;
  258.       jle     octant2L           ;
  259.       ror     al,1               ; Compute X := X + 1;
  260.       adc     bx,0               ;   ...
  261.       sub     di,[bp+6]           ;
  262.       jmp     short octant2L        ;
  263.  
  264. octant7:
  265.       mov     cx,di               ; Count Down = DY
  266.       shr     di,1               ; Error Register = -DY/2
  267.       neg     di               ;   ...
  268.       les     si,_gdstyle
  269.       mov     ah,es:[si]
  270.       inc     si
  271. octant7L:
  272.       call     putdot
  273.  
  274.       sub     bx,80               ; Compute Y := Y + 1;
  275.       add     di,[bp+4]           ;
  276.       jle     octant7L           ;
  277.       ror     al,1               ; Compute X := X + 1;
  278.       adc     bx,0               ;   ...
  279.       add     di,[bp+6]           ;
  280.       jmp     short octant7L        ;
  281.  
  282. octant8:
  283.       mov     cx,si               ; Count Down = DX
  284.       mov     di,si               ; Error Register = -DX/2
  285.       shr     di,1               ;   ...
  286.       neg     di               ;   ...
  287.       les     si,_gdstyle
  288.       mov     ah,es:[si]
  289.       inc     si
  290. octant8L:
  291.       call     putdot
  292.  
  293.       ror     al,1               ; Compute X := X + 1;
  294.       adc     bx,0               ;   ...
  295.       sub     di,[bp+6]           ;
  296.       jle     octant8L           ;
  297.       sub     bx,80               ; Compute Y := Y + 1;
  298.       sub     di,[bp+4]           ;
  299.       jmp     short octant8L        ;
  300. line:
  301.       mov     ah,_gdcolor           ; Load current color setting
  302.       push     bp
  303.       mov     es,_gdgseg
  304.       or     di,di
  305.       jns     line01
  306.       neg     di
  307.       cmp     di,si
  308.       ja     lineoct7
  309.       jmp     short lineoct8
  310. line01:
  311.       cmp     di,si
  312.       ja     lineoct2
  313.  
  314. lineoct1:
  315.       mov     cx,si               ; Count Down = DX
  316.       mov     bp,si               ; Error Register = -DX/2
  317.       shr     bp,1               ;   ...
  318.       neg     bp               ;   ...
  319. lineoct1L:
  320.       out     dx,al
  321.       cmp     byte ptr es:[bx],0
  322.       mov     es:[bx],ah
  323.       dec     cx
  324.       js     linedone
  325.       ror     al,1
  326.       adc     bx,0
  327.       add     bp,di
  328.       jle     lineoct1L
  329.       add     bx,80
  330.       sub     bp,si
  331.       jmp     short lineoct1L
  332.  
  333. lineoct2:
  334.       mov     cx,di               ; Count Down = DY
  335.       mov     bp,di               ; Error Register = -DY/2
  336.       shr     bp,1               ;   ...
  337.       neg     bp               ;   ...
  338. lineoct2L:
  339.       out     dx,al
  340.       cmp     byte ptr es:[bx],0
  341.       mov     es:[bx],ah
  342.       dec     cx
  343.       js     linedone
  344.       add     bx,80
  345.       add     bp,si
  346.       jle     lineoct2L
  347.       ror     al,1
  348.       adc     bx,0
  349.       sub     bp,di
  350.       jmp     short lineoct2L
  351.  
  352. lineoct7:
  353.       mov     cx,di               ; Count Down = -DY
  354.       mov     bp,di               ; Error Register = DY/2
  355.       shr     bp,1               ;   ...
  356.       neg     bp               ;
  357. lineoct7L:
  358.       out     dx,al
  359.       cmp     byte ptr es:[bx],0
  360.       mov     es:[bx],ah
  361.       dec     cx
  362.       js     linedone
  363.       sub     bx,80
  364.       add     bp,si
  365.       jle     lineoct7L
  366.       ror     al,